package edu.wit.common.db.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import edu.wit.common.core.web.page.TableSupport;
import edu.wit.common.db.BaseDao;
import edu.wit.common.db.service.BaseService;
import edu.wit.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

/**
 * @author yyh
 * @create 2020-07-30 15:52
 */
public class BaseServiceImpl<K extends BaseDao<T>, T> extends ServiceImpl<K, T> implements BaseService<K, T> {

    @Value("${mybatis-plus.global-config.db-config.logic-enable}")
    private Boolean logicEnable;
    @Value("${mybatis-plus.global-config.db-config.logic-delete-field}")
    private String logicDeleteField;

    @Override
    public K getBaseMapper() {
        return super.getBaseMapper();
    }

    @Override
    public PageInfo<T> basePageList(Map<String, Object> columnMap) {
        return basePageList(columnMap, null);
    }

    @Override
    public PageInfo<T> basePageList(Map<String, Object> columnMap, String orderBy) {
        if(StringUtils.isBlank(orderBy)){
            try{
                Class<T> clazz = getClassT();
                Field createTime = null;
                try{
                    // 获取父类的创建时间
//                    createTime = clazz.getSuperclass().getDeclaredField(StringUtils.lineToHump(CommonConstant.BaseField.CREATE_TIME));
                    createTime = clazz.getSuperclass().getDeclaredField(StringUtils.lineToHump("create_time"));
                } catch (Exception ignored){}
                try{
                    // 获取自己的创建时间
//                    createTime = clazz.getDeclaredField(StringUtils.lineToHump(CommonConstant.BaseField.CREATE_TIME));
                    createTime = clazz.getDeclaredField(StringUtils.lineToHump("create_time"));

                } catch (Exception ignored){}
                if(createTime != null){
                    // 存在，则添加默认排序
//                    orderBy = CommonConstant.BaseField.CREATE_TIME + " " + "desc";
                    orderBy = "create_time" + " " + "desc";

                }
            } catch (Exception ignored){}
        }

        TableSupport.startPage(orderBy);
        List<T> list = baseFindList(columnMap);
        return new PageInfo<>(list);
    }

    @Override
    public List<T> baseFindList(Map<String, Object> columnMap) {
        return baseFindList(columnMap, null);
    }

    @Override
    public List<T> baseFindList(Map<String, Object> columnMap, String orderBy) {
        return baseFindList(columnMap,orderBy,true);
    }

    @Override
    public List<T> baseFindList(Map<String, Object> columnMap, String orderBy,Boolean isVisible) {
        if (StringUtils.isNotBlank(orderBy)) {
            PageHelper.orderBy(orderBy);
        }
        if (logicEnable && isVisible) {
            addLogicDeleteField(columnMap);
        }
        return baseMapper.findList(columnMap);
    }

    /**
     * 获取泛型 T 的class对象
     */
    @SuppressWarnings("unchecked")
	private Class<T> getClassT(){
        Class<T> actualTypeArgument = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        return actualTypeArgument;
    }

    /**
     * 查询条件添加逻辑删除字段
     *
     * @param columnMap 搜索条件
     */
	private void addLogicDeleteField(Map<String, Object> columnMap) {
        try {
            Class<T> clazz = getClassT();
            Field visible = clazz.getDeclaredField(logicDeleteField);
            if (visible != null) {
//                columnMap.put(logicDeleteField, CommonConstant.YesNo.YES_INT);
                columnMap.put(logicDeleteField, 1);
            }
        } catch (Exception e) {
        }
    }

	@Override
    public int baseLogicDelete(T entity, LambdaUpdateWrapper<T> updateWrapper) {
        if(entity == null){
            Class<T> clzz = getClassT();
            try{
                // 为空时，初始化一个泛型<T>对象
                entity = clzz.newInstance();
            } catch (Exception ignored){

            }
        }
//        updateWrapper.setSql(logicDeleteField + "=" + CommonConstant.YesNo.NO_INT);
        updateWrapper.setSql(logicDeleteField + "=" + 1);

        return baseMapper.update(entity, updateWrapper);
    }

    @Override
    public int baseLogicDelete(LambdaUpdateWrapper<T> updateWrapper) {
        return baseLogicDelete(null, updateWrapper);
    }
}
